<template>
	<div class="custom-tree-tab-wrap">
		<div class="heade-wrapper">
			<a-input-search
				v-model="searchValue"
				:placeholder="placeText"
				@search="onSearch"
			/>
		</div>
		<top-bottom-layout class="content-wrapper" :isShowDown="isShowDown">
			<template #top>
				<base-business-tree
					:treeData="treeData"
					:defaultExpandedKeys="defaultExpandedKeys"
					:tabMainInfo="tabMainInfo"
					@toCheckedNode="onCheckedNode"
				/>
			</template>
			<template #bottom>
				<scrollList
					ref="scrollList"
					:panel="tabMainInfo.name"
					:command="displayType"
					:firstLoadSearch="firstLoadSearch"
					:showOtherProp="otherParams.showOther"
					:otherProps="otherParams.otherLabels"
					:listDataHandler="listDataHandler"
					@toCheckValueClickProp="onCheckValueClickProp"
				>
				</scrollList>
			</template>
		</top-bottom-layout>
	</div>
</template>

<script>
import topBottomLayout from '@/components/topBottomLayout.vue';
import chooseList from '@/components/chooseList';
import baseBusinessTree from '@/components/baseBusinessTree.vue';
import scrollList from '@/components/scrollList';

import {getPanelData} from '@/api/modules/SelectOrgApi';

import {nodeChildrenCheck} from '@/utils/tree.js';

import {mapActions, mapState} from 'vuex';
import {ACTION_ADD_ENTITY, ACTION_REMOVE_ENTITY} from '@/store/actionTypes.js';

import {BtnType, Dialog} from '@/components/dialog';
import {CheckUtils} from '@/utils/checkUtils';
import { getSelectKey, isSubDeptType } from '@/utils/utils';
import { EntityTypes } from '@/utils/orgConstants.js';

export default {
	name: 'customTreeTab',
	components: {
		topBottomLayout,
		chooseList,
		baseBusinessTree,
		scrollList
	},
	props: {
		/** 【必填参数】*/
		/** 页签的主数据 */
		tabMainInfo: {
			type: Object, default: () => {
			}
		}
	},
	inject: ['app'],
	data() {
		return {
			searchValue: '',

			treeData: [],
			defaultExpandedKeys: [],

			firstLoadSearch: false,
			scrollParams: {
				panel: '',
				command: ''
			},
			otherParams: {
				showOther: '',
				otherLabels: []
			},

			checkNodeData: {
				checkeds: [],
				ids: []
			},
			// 当前单位及部门数据集合
			unitIds: [],

			// 默认隐藏左下角内容
			isShowDown: true,

			serachParams: {}
		};
	},
	computed: {
		...mapState('selectData', ['selectedUUIDMap', 'selectedEntityMap']),
		displayType() {
			return this.tabMainInfo.extInfo.displayType;
		},
		orgSelectType() {
			return this.app().orgSelect.selectType;
		},
		selectType() {
			return this.tabMainInfo.extInfo.selectType;
		},
		orgSelect() {
			return this.app().orgSelect;
		},
		runMode() {
			return this.app().runMode;
		},
		placeText() {
			return this.onSetPlaceText();
		}
	},
	watch: {},
	methods: {
		...mapActions('selectData', [ACTION_ADD_ENTITY, ACTION_REMOVE_ENTITY]),
		/** 加载table数据 */
		async onLoadTreeData(data) {
			let res = await getPanelData(data);
			if (res.code === 0) {
				// 绑定唯一标识
				this.treeData = this.onSetNodeSeletKey(res.data);
				// checkbox 显示|隐藏 处理
				this.onSetTreeNodeCheckbox(this.treeData);
				// 调用仿真时间回填函数
				if (this.runMode === 'SIMULATION') {
					const simulationTime = res.cost;
					window.parent.CostTimeSelectTab(simulationTime);
				}
				if (this.treeData.length) {
					this.$set(this.defaultExpandedKeys, 0, this.treeData[0].id);
				}
			}
		},
		/**
		 * checkbox 显示|隐藏 处理
		*/
		onSetTreeNodeCheckbox(nodes) {
			let maxSize = this.orgSelect.maxSize;
			if (Number(maxSize) !== 1 || !this.orgSelectType.includes(EntityTypes.Member)) {
				return;
			}

			for (let node of nodes) {
				node.nocheck = !(node.type === EntityTypes.Member);
				if (node.children && node.children.length) {
					this.onSetTreeNodeCheckbox(node.children);
				}
			}
		},
		onSearch(val) {
			console.log('val', val);
			if (val) {
				this.isShowDown = false;
				this.onSearchData({ keyword: val, ...this.serachParams });
			} else {
				this.isShowDown = true;
				this.$refs.scrollList.initProps();
			}
		},
		onSearchData(data) {
			this.firstLoadSearchInner = true;
			this.$refs.scrollList.initProps();
			this.$refs.scrollList.search(data);
		},
		onCheckValueClickProp(data) {
			console.log('data', data);
		},

		/** 检查范围方法 */
		async onCheckScopeStatus(nodes) {
			let entity = nodes[0];
			let currentPanel = entity.type;
			let notIncludeSubDept = [];
			let checkContext = {
				currentPanel: currentPanel,
				notIncludeSubDept
			};
			let result = await CheckUtils.doCheckEntity(entity, checkContext);
			if (!result) {
				return;
			}
			this.selectDataToRight(nodes);
		},
		/** 在点击树形节点复选框之前根据 displayType 判断交互方式
		 * @params nodeData {Object} nodeData = { checkeds, ids }
		 * 1：displayType = Group 点击对象有子节点直接勾选其所有子节点
		 * 2：displayType = Tree  点击对象有子节点需要弹窗提示是否勾选子节点
		 */
		async onCheckedNode(nodeData, nodeEl) {
			let { nodesNum, checkedNodesNum } = nodeChildrenCheck(
				nodeData.checkeds[0].children,
				this.selectedEntityMap
			);

			console.log('nodesNum', nodesNum);
			console.log('checkedNodesNum', checkedNodesNum);

			switch (this.displayType) {
			case 'Group':
				this.onGroupCheckedNode(nodeData, nodeEl, {
					nodesNum,
					checkedNodesNum
				});
				break;
			case 'Tree':
				this.onTreeCheckedNode(nodeData, nodeEl, {
					nodesNum,
					checkedNodesNum
				});
				break;
			}
		},
		/**
		 * displayType = Group 勾选子节点方法
		 * 交互：根节点相当于【全选】按钮，点击父节点时只会全选子节点
		 */
		onGroupCheckedNode(nodeData, nodeEl, nodeCheckData) {
			this.unitIds = [];
			let { nodesNum, checkedNodesNum } = nodeCheckData;
			let checkeds = nodeData.checkeds;
			if (checkeds[0].children.length) {
				this.onGetNodesChildrenId(checkeds[0].children);
				if (nodesNum === checkedNodesNum) {
					this[ACTION_REMOVE_ENTITY]({ entities: this.unitIds });
				} else {
					this[ACTION_ADD_ENTITY]({ entities: this.unitIds });
				}
			} else {
				this.selectDataToRight(checkeds);
			}
		},

		/** displayType = Tree 勾选子节点方法 */
		async onTreeCheckedNode(nodeData, nodeEl) {
			this.checkNodeData = nodeData;
			let checkNodeStatus = nodeEl.checked;
			let activeCheckNode =
				this.checkNodeData.checkeds[this.checkNodeData.checkeds.length - 1];

			let maxSize = this.orgSelect.maxSize;
			// 单选处理
			if (Number(maxSize) == 1) {
				if (String(activeCheckNode.orgType) !== '3') {
					this.onCheckScopeStatus([activeCheckNode]);
				}
				return;
			}
			// 处理树上挂人员时取消勾选子节点
			let checkedNodes = this.getAllChildren(activeCheckNode.children, true);
			if (this.orgSelectType.includes(EntityTypes.Member) && checkedNodes.length > 0) {
				let btnType = await Dialog.confirm(`"${activeCheckNode.name}"是否取消勾选子节点?`);
				if (btnType === BtnType.CLOSE) {
					return;
				}
				if (btnType === BtnType.CANCEL) {
					checkedNodes = [];
					return;
				}
				checkedNodes.push(activeCheckNode)
				this[ACTION_REMOVE_ENTITY]({
					entities: checkedNodes
				});
				return;
			}
			if (checkNodeStatus) {
				// 取消勾选:是否取消勾选子单位
				let nodes = this.getAllChildren(activeCheckNode.children, true);
				if (nodes.length > 0) {
					let btnType = await Dialog.confirm(`"${activeCheckNode.name}"是否取消勾选子节点?`);
					if (btnType === BtnType.CLOSE) {
						return;
					}
					if (btnType === BtnType.CANCEL) {
						nodes = [];
					}
				}
				nodes.push(activeCheckNode);
				this[ACTION_REMOVE_ENTITY]({
					entities: nodes
				});
			} else {
				let entities = [];
				let notIncludeSubDept = [];
				if (activeCheckNode.$_excludeChildDepartment) {
					notIncludeSubDept.push(activeCheckNode.id);
				}
				// 有子单位
				if (activeCheckNode.children && activeCheckNode.children.length > 0) {
					let btnType = await Dialog.confirm({
						msg: `"${activeCheckNode.name}"是否勾选子节点?`,
						okText: '勾选',
						cancelText: '不勾选'
					});
					if (btnType === BtnType.CLOSE) {
						return;
					}
					if (btnType === BtnType.CANCEL) {
						notIncludeSubDept.push(activeCheckNode.id);
					}
					// 包含子单位
					let nodes = [];
					if (btnType === BtnType.OK) {
						nodes = this.getAllChildren(activeCheckNode.children, false);
					}
					nodes.unshift(activeCheckNode);
					for (const currentNode of nodes) {
						let rs = await CheckUtils.doCheckEntity(currentNode);
						if (!rs) {
							continue;
						}
						entities.push(currentNode);
					}
				}
				// 没子单位
				if (activeCheckNode.children.length === 0) {
					let rs = await CheckUtils.doCheckEntity(activeCheckNode);
					if (rs) {
						entities.push(activeCheckNode);
					}
				}

				this[ACTION_ADD_ENTITY]({
					entities,
					notIncludeSubDept: notIncludeSubDept
				});
			}
		},
		getAllChildren(children, includeChecked) {
			if (!children || children.length === 0) {
				return [];
			}
			let nodes = [];
			for (let child of children) {
				let myChildren = this.getAllChildren(child.children, includeChecked);
				nodes = [...nodes, ...myChildren];
				let entity = {...child, ...child.data };
				let uuid = entity.type + '|' + entity.id;
				if (includeChecked === true ) {
					if (this.selectedUUIDMap[uuid]) {
						nodes.push(entity);
					}
				} else if (includeChecked === false) {
					if (!this.selectedUUIDMap[uuid]) {
						nodes.push(entity);
					}
				} else {
					nodes.push(entity);
				}
			}
			return nodes;
		},

		onGetNodesChildrenId(nodes) {
			for (let i = 0; i < nodes.length; i++) {
				if (String(nodes[i].orgType) !== '3') {
					this.unitIds.push(nodes[i]);
				}
				if (nodes[i].children && nodes[i].children.length > 0) {
					this.onGetNodesChildrenId(nodes[i].children);
				}
			}
		},
		/**
		 * 动态设置placeholder提示
		 */
		onSetPlaceText() {
			let text = this.onSetI18n(this.$i18n('common.personnel.label'));
			if (this.displayType === 'Group') {
				return text;
			}
			if (this.displayType === 'Tree') {
				const canSelectType = this.onSetPanelSelectType(this.selectType, this.orgSelectType);
				text = this.onSetI18n(this.$i18n(this.onSetPlaceAfterText(canSelectType)));
			}
			return text;
		},
		onSetI18n(data) {
			return this.$i18n('selectPeople.input', data);
		},
		/**
		 * 处理可选类型
		 * @param {Array} 全量可选数据
		 * @param {Array} 组件可以数据
		*/
		onSetPanelSelectType(tabSelectType, panelSelectType) {
			return tabSelectType.filter(type => {
				return panelSelectType.indexOf(type) !== -1;
			});
		},
		/**
		 * 提示文案处理(请输入后的文案处理)
		 * @param {Array} selectTypes 可选类型数组
		 * @return {String} 返回提示文案
		*/
		onSetPlaceAfterText(selectTypes) {
			let text = '';
			for (let type of selectTypes) {
				switch (type) {
				case EntityTypes.Account:
					text = text ? text + '/' + this.$i18n('common.company.label') : this.$i18n('common.company.label');
					break;
				case EntityTypes.BusinessAccount:
					text = text ? text + '/' + this.$i18n('common.company.label') : this.$i18n('common.company.label');
					break;
				case EntityTypes.BusinessDepartment:
					text = text ? text + '/' + this.$i18n('message_onlineUser_department') : this.$i18n('message_onlineUser_department');
					break;
				case EntityTypes.Department:
					text = text ? text + '/' + this.$i18n('message_onlineUser_department') : this.$i18n('message_onlineUser_department');
					break;
				case EntityTypes.Member:
					text = text ? text + '/' + this.$i18n('common.personnel.label') : this.$i18n('common.personnel.label');
					break;
				case EntityTypes.OrgTeam:
					text = text ? text + '/' + this.$i18n('org.orgTeam.label') : this.$i18n('org.orgTeam.label');
					break;
				}
			}
			return text;
		},
		/**
		 * 给树节点绑定$_selectkey
		 * @param {Array} 源数组
		*/
		onSetNodeSeletKey(treeDataList) {
			return treeDataList.map(node => {
				let children = node.children;
				if (node.data) {
					node = {...node, ...node.data, children}
				}
				node.$_showLabel = node.name;
				// 处理部门id去除id后带的 '|1'
				let ids = node.id.split('|');
				if (isSubDeptType(node) && ids.length > 1) {
					node.id = ids[0];
					if (node.data) {
						node.data.id = ids[0];
					}
					node.$_excludeChildDepartment = true;
				}
				node.$_selectKey = getSelectKey(node);

				if (node.children && node.children.length) {
					node.children = this.onSetNodeSeletKey(node.children);
				}
				return node;
			})
		},
		/**
		 * 处理搜索后的参数
		 * @param {Array} list
		*/
		listDataHandler(list) {
			return this.onSetNodeSeletKey(list);
		}
	},
	created() {
		let { name } = this.tabMainInfo;
		let { isNeedCheckLevelScope,
			showTeamType,
			showRoleType,
			accessFileSecretLevel,
			includeElements,
			excludeElements,
			returnMemberWithDept,
			memberWithDeptInfo,
			showAllOuterDepartment,
			appParams,
			runMode,
			selectType } = this.orgSelect;

		this.serachParams = { isNeedCheckLevelScope,
			showTeamType,
			showRoleType,
			accessFileSecretLevel,
			includeElements,
			excludeElements,
			returnMemberWithDept,
			memberWithDeptInfo,
			showAllOuterDepartment,
			appParams,
			selectType};

		this.onLoadTreeData({
			panel: name,
			command: this.displayType,
			arguments: { ...this.serachParams },
			runMode
		});
	},
	mounted() {
	}
};
</script>

<style scoped lang="scss">
@import "@/css/theme.scss";
.custom-tree-tab-wrap {
	width: 100%;
	height: 100%;
}
.search-box{
	display: flex;
	box-sizing: border-box;
}
.top-bottom-layout {
	border: 1px solid #d9d9d9;
	border-right: 0;
	height: calc(100% - 32px);
	border-top: 0;
}
</style>
